//
// Created by 84000 on 2022/4/8.
//

#ifndef DATASTRUCTURES_MATRIX_H
#define DATASTRUCTURES_MATRIX_H
#include <initializer_list>
#include <algorithm>

template<typename T>
class Matrix {
public:
    using size = long long unsigned int;

    Matrix(size row, size column, std::initializer_list<T> elements);
    Matrix(size row, size column, const T& element);
    Matrix(const Matrix<T>& rhs);
    Matrix<T>& operator=(const Matrix<T>& rhs);

    static Matrix<double> zeors(size d);
private:
    T*  elements_;
    size column_;
    size row_;
};

template<typename T>
Matrix<T>::Matrix(Matrix::size row, Matrix::size column, std::initializer_list<T> elements)
  : column_(column),
    row_(row)
{
    elements_ = new T[column * row];
    std::copy(&*elements.begin(), &*elements.begin() + column * row, elements);
}

template<typename T>
Matrix<T>::Matrix(const Matrix<T> &rhs)
 : column_(rhs.column_),
   row_(rhs.row_)
{
    elements_ = new T[column_ * row_];
    std::copy(rhs.elements_, rhs.elements_ + row_ * column_, elements_);
}

template<typename T>
Matrix<T>& Matrix<T>::operator=(const Matrix<T> &rhs){
    column_ = rhs.column_;
    row_ = rhs.row_;
    elements_ = new T[column_ * row_];
    std::copy(rhs.elements_, rhs.elements_ + row_ * column_, elements_);
    return *this;
}

template<typename T>
Matrix<double> Matrix<T>::zeors(Matrix::size d) {
    return {d, d, 0};
}

template<typename T>
Matrix<T>::Matrix(Matrix::size row, Matrix::size column, const T &element)
  : row_(row),
    column_(column)
{
    elements_ = new T[column_ * row_];
    for (int i = 0; i < column_ * row_; i++)
        elements_[i] = element;
}


#endif //DATASTRUCTURES_MATRIX_H
